package com.zr.service.impl;

import com.zr.constants.FileConstant;
import com.zr.dto.MenuDTO;
import com.zr.dto.StaffFileDTO;
import com.zr.dto.staff.StaffDetailInfoRequest;
import com.zr.entity.Menu;
import com.zr.entity.Staff;
import com.zr.entity.StaffFile;
import com.zr.enums.CoreExceptionEnum;
import com.zr.exception.ServiceException;
import com.zr.mapper.StaffFileMapper;
import com.zr.mapper.StaffMapper;
import com.zr.service.IStaffService;
import com.zr.utils.BeanHelper;
import com.zr.utils.FilesUtils;
import com.zr.vo.StaffFileVO;
import com.zr.vo.StaffVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author: peterChen
 * @date: 2019/11/14 20:48
 * @description: com.zr.service
 * @version: 1.0
 */
@Slf4j
@Service
public class StaffServiceImpl implements IStaffService {
    @Autowired
    private StaffMapper staffMapper;
    @Autowired
    private StaffFileMapper stafffileMapper;

    private static final String FILE_DIR = FileConstant.FILE_DIR;
    /**
     * 单个添加员工信息
     * @param staffVO
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void addStaff(StaffVO staffVO) {
        Staff staff = BeanHelper.copyProperties(staffVO, Staff.class);
        List<StaffFileVO> stafffileVOS = staffVO.getStaffFiles();
        //判断该员工是否已添加
        int count = staffMapper.selectCount(staff);
        if(count == 1){
            log.error("该员工信息已添加！");
            throw new ServiceException(CoreExceptionEnum.DATA_ALREADY_EXISTS);
        }
        count = staffMapper.insertSelective(staff);
        if(count == 0){
            log.error("员工添加失败");
            throw new ServiceException(CoreExceptionEnum.INSERT_OPERATION_FAIL);
        }
        if(!CollectionUtils.isEmpty(stafffileVOS)) {
            List<StaffFile> staffFiles = BeanHelper.copyWithCollection(stafffileVOS, StaffFile.class);
            staffFiles.stream().forEach(staffFile -> staffFile.setStaffId(staff.getId()));
            count = stafffileMapper.insertStaffFile(staffFiles);
            if (count != staffFiles.size()) {
                log.error("员工上传附件失败");
                throw new ServiceException(CoreExceptionEnum.INSERT_OPERATION_FAIL);
            }
        }

    }


    /**
     * 批量导入excel表中员工信息
     * @param list
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void add(List<String[]> list) {
        if (list != null && list.size() > 0) {
            List<StaffVO> staffVOList = new ArrayList<>();
            for (String[] strings : list) {
                StaffVO staffVO =
                        new StaffVO(strings[0], strings[1], new Date(strings[2]), (strings[3].equals("男") ? 1 : 2),
                                strings[4], (strings[5].equals("是")? 1 : 2), (strings[6].equals("是")? 1 : 2),
                                Integer.parseInt(strings[7]), Integer.parseInt(strings[8]),
                                new Date(strings[9]), strings[10], strings[11], strings[12], strings[13], strings[14],
                                Integer.parseInt(strings[15]), strings[16],strings[17],strings[18]);
                staffVOList.add(staffVO);
            }
            //转换为实体类
            List<Staff> staffList = BeanHelper.copyWithCollection(staffVOList, Staff.class);

            //方案一：直接批量导入，不需要判断添加的员工是否已添加
            //批量添加
            //if (!CollectionUtils.isEmpty(staffList)) {
            //    int count = staffMapper.insertStaffList(staffList);
            //    log.info("count:" + count);
            //    if (count != staffList.size()) {
            //        log.error("员工批量导入失败");
            //        throw new ServiceException(CoreExceptionEnum.INSERT_OPERATION_FAIL);
            //    }
            //}
            //方案二：业务层进行查询判断，已添加则进行更新，未添加则进行添加
            //批量添加
            ArrayList<Staff> staffExists = new ArrayList<>();
            staffList.stream().forEach(staff -> {
                Staff sta = staffMapper.selectByIdentificationNum(staff.getIdentificationNum());
                if(sta != null){
                    log.error("请检查传入员工信息是否已存在");
                    throw new ServiceException(CoreExceptionEnum.INSERT_OPERATIONS_FAIL);
                }
            });

            int count = staffMapper.insertStaffList(staffList);
            if (count != staffList.size()) {
                log.error("员工批量导入失败");
                throw new ServiceException(CoreExceptionEnum.INSERT_OPERATION_FAIL);
            }
        }
    }



    /**
     * 获取所有菜单（含子菜单）
     * @return
     */
    @Override
    public List<MenuDTO> getAllMenus(Integer roleId) {
        List<Menu> menus = staffMapper.getParentMenus(roleId);
        if(CollectionUtils.isEmpty(menus)){
            throw new ServiceException(CoreExceptionEnum.UNAUTHORIZED);
        }
        List<MenuDTO> menuDTOS = BeanHelper.copyWithCollection(menus, MenuDTO.class);
        //TODO 待实现递归查询子菜单
        menuDTOS.stream()
                .forEach(menuDTO -> {
                    List<Menu> childMenus = staffMapper.getChildMenusByParentId(menuDTO.getId());
                    if(childMenus != null && childMenus.size() > 0){
                        menuDTO.setChildren(BeanHelper.copyWithCollection(childMenus,MenuDTO.class));
                    }
                });
        return menuDTOS;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public List<StaffFileDTO> uploadFiles(MultipartFile[] files) {
        //创建集合接收上传文件返回的文件地址
        ArrayList<StaffFileDTO> fileList = new ArrayList<>();

        try {
            if (files.length == 0) {
                throw new ServiceException(CoreExceptionEnum.INVALID_PARAM_ERROR);
            } else {
                for (MultipartFile file : files) {
                    //判断文件是否小于5M
                    if (FilesUtils.checkFileSize(file, 5, "M")) {
                        //逐个上传文件，返回上传的信息
                        StaffFileDTO staffFileDTO = transferFile(file);
                        fileList.add(staffFileDTO);
                    }
                }
            }
        }catch (IOException e){
            log.error("文件异常：{}",e.getMessage());
            throw new ServiceException(CoreExceptionEnum.FILE_UPLOAD_ERROR);
        }
        return fileList;
    }
    /**
     * 上传文件并返回文件地址
     * @param file
     * @return
     */
    private StaffFileDTO transferFile(MultipartFile file) throws IOException {
        // 文件地址
        // 1.文件名
        String filename = file.getOriginalFilename();
        String contentType = file.getContentType();
        // 2.后缀名
        String extension = StringUtils.substringAfterLast(filename, ".");
        // 3.目标文件地址
        String uuidFilename = UUID.randomUUID().toString() + "." + extension;
        File filePath = new File(FILE_DIR, uuidFilename);
        // 4.保存文件
        try {
            file.transferTo(filePath);
        } catch (IOException e) {
            log.error("文件上传失败，原因：{}", e.getMessage());
            throw new ServiceException(CoreExceptionEnum.FILE_UPLOAD_ERROR);
        }
        StaffFileDTO staffFileDTO = new StaffFileDTO(FILE_DIR + uuidFilename, filename, uuidFilename, contentType);
        // 5.返回url
        return staffFileDTO;
    }

    @Override
    public Staff getInfoById(StaffDetailInfoRequest staffDetailInfoRequest) {
        return staffMapper.getInfoById(staffDetailInfoRequest);
    }

    @Override
    public List<Staff> getAll() {
        return staffMapper.getAll();
    }


}
